﻿using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Ast.Core.WinApi.DbgHelp
{
    public static class DbgHelpNative
    {
        public delegate bool SymEnumSymbolsProc(ref DbgHelpStructure.SymbolInfo pSymInfo, uint SymbolSize, IntPtr UserContext);

        public delegate bool SymEnumerateModulesProc64(string ModuleName, ulong BaseOfDll, IntPtr UserContext);

        public delegate bool EnumerateLoadedModulesProc64(string ModuleName, ulong ModuleBase, uint ModuleSize, IntPtr UserContext);

        public delegate bool SymRegisterCallbackProc64(IntPtr hProcess, DbgHelpConstant.SymActionCode ActionCode, ulong CallbackData, ulong UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern DbgHelpConstant.SymOption SymGetOptions();

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern DbgHelpConstant.SymOption SymSetOptions(DbgHelpConstant.SymOption SymOptions);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymGetSearchPath(IntPtr hProcess, StringBuilder SearchPath, int SearchPathLength);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymSetSearchPath(IntPtr hProcess, string SearchPath);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, bool fInvadeProcess);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymCleanup(IntPtr hProcess);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern ulong SymLoadModule64(IntPtr hProcess, IntPtr hFile, string ImageName, string ModuleName, ulong BaseOfDll, int SizeOfDll);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymUnloadModule64(IntPtr hProcess, ulong BaseOfDll);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile, string ImageName, string ModuleName, ulong BaseOfDll, int DllSize, IntPtr Data, int Flags);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymEnumSymbols(IntPtr hProcess, ulong BaseOfDll, string Mask, SymEnumSymbolsProc EnumSymbolsCallback, IntPtr UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymEnumSymbolsForAddr(IntPtr hProcess, ulong Address, SymEnumSymbolsProc EnumSymbolsCallback, IntPtr UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymFromName(IntPtr hProcess, string Name, ref DbgHelpStructure.SymbolInfo Symbol);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymFromAddr(IntPtr hProcess, ulong Address, ref ulong Displacement, ref DbgHelpStructure.SymbolInfo Symbol);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymFromIndex(IntPtr hProcess, ulong BaseOfDll, uint Index, ref DbgHelpStructure.SymbolInfo Symbol);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymGetModuleInfo64(IntPtr hProcess, ulong dwAddress, ref DbgHelpStructure.ImagehlpModule64 ModuleInfo);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymEnumerateModules64(IntPtr hProcess, SymEnumerateModulesProc64 EnumModulesCallback, IntPtr UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool EnumerateLoadedModules64(IntPtr hProcess, EnumerateLoadedModulesProc64 EnumLoadedModulesCallback, IntPtr UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymRegisterCallback64(IntPtr hProcess, SymRegisterCallbackProc64 CallbackFunction, ulong UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int UnDecorateSymbolName(string DecoratedName, StringBuilder UnDecoratedName, int UndecoratedLength, DbgHelpConstant.SymUndecorateOption Flags);
        
        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymGetTypeFromName(IntPtr hProcess, ulong BaseOfDll, string Name, ref DbgHelpStructure.SymbolInfo Symbol);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymGetTypeInfo(IntPtr hProcess, ulong ModuleBase, uint TypeId, DbgHelpConstant.ImagehlpSymbolTypeInfo GetType, IntPtr pInfo);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymSearch(IntPtr hProcess, ulong BaseOfDll, uint Index, DbgHelpConstant.SymTagEnum SymTag, string Mask, ulong Address, SymEnumSymbolsProc EnumSymbolsCallback, IntPtr UserContext, DbgHelpConstant.SymSearchOption Options);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymEnumTypes(IntPtr hProcess, ulong BaseOfDll, SymEnumSymbolsProc EnumSymbolsCallback, IntPtr UserContext);

        [DllImport("dbghelp.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SymSetContext(IntPtr hProcess, ref DbgHelpStructure.ImagehlpStackFrame StackFrame, IntPtr Context);
    }
}